package com.eric.study.jobflow.graph;

import com.eric.study.jobflow.job.JobNode;
import lombok.NonNull;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * <p> JobNodeDigraph.
 *
 * <p>
 * change history:
 *
 * <pre>
 * date         defect       person          comments
 * --------------------------------------------------------------------------------
 * 2023/8/31    ********     Eric    create file.
 * </pre>
 *
 * @author Eric
 * @date 2023/8/31 10:55
 * @copyright 2023, FA Software (Shanghai) Co., Ltd. All Rights Reserved.
 * @since 1.0.0
 */
public class JobNodeDigraph extends Digraph<Integer> {

    private final Map<Integer, JobNode<?, ?>> nodes;

    public JobNodeDigraph() {
        this.nodes = new HashMap<>();
    }

    public void addNode(@NonNull JobNode<?, ?> node) {
        this.nodes.put(node.getNumber(), node);
    }

    public Set<JobNode<?, ?>> allNodes() {
        return new HashSet<>(this.nodes.values());
    }

    public Map<Integer, JobNode<?, ?>> nodeMap() {
        return this.nodes;
    }


    /**
     * 添加节点之间的关系，即有向图中的边（由节点 {@code node1 -> node2}）
     *
     * @param node1 节点1
     * @param node2 节点2
     * @author Qiheng Zhang
     * @date 2023/9/1 09:40
     * @since 1.0.0
     */
    public void addEdge(@NonNull JobNode<?, ?> node1, JobNode<?, ?> node2) {
        if (null == node2) {
            super.addEdge(node1.getNumber(), null);

        } else {
            // 判断边是否已经存在
            if (!hasEdgeAlreadyExisted(node1.getNumber(), node2.getNumber())) {
                // 添加边
                super.addEdge(node1.getNumber(), node2.getNumber());

                // 节点 node1 出度加一
                node1.outDegreeIncrement();

                // 节点 node2 入度加一
                node2.inDegreeIncrement();
            }

            // 添加节点之间的关系
            node1.getNextNodes().add(node2);
            node2.getPreviousNodes().add(node1);
        }
    }
}
